package com.ops.uitl.data;


import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import java.util.Map.Entry;
import java.util.*;

public class DataMap extends HashMap implements IData {
	
	/**
	 * construct function
	 */
	public DataMap() {
		super();
	}
	
	/**
	 * construct function
	 * @param value
	 */
	public DataMap(String value) {
		List list = DataHelper.strToList(value);
		if (list != null && list.size() > 0) putAll((Map) list.get(0));
	}
	
	/**
	 * get object
	 * @param name
	 * @return Object
	 */
	public Object get(Object name) {
		Object value = super.get(name);
		if (value == null) return null;
		
		if (value instanceof JSONObject) {
			IData data = new DataMap();
			data.putAll((JSONObject) value);
			value = data;
		} else if (value instanceof JSONArray) {
			IDataset dataset = new DatasetList();
			dataset.addAll((JSONArray) value);
			value = dataset;
		}
		
		put(name, value);
		
		return value;
	}
	
	/**
	 * get object
	 * @param name
	 * @param def
	 * @return Object
	 */
	public Object get(String name, Object def) {
		Object value = get(name);
		return value == null ? def : value;
	}

	/**
	 * get names
	 * @return String[]
	 */
	public String[] getNames() {
		return getNames(true);
	}
	
	/**
	 * get names 
	 * @param sort
	 * @return
	 */
	public String[] getNames(boolean sort) {
		String[] names = (String[]) keySet().toArray(new String[0]);
		if (sort) Arrays.sort(names);
		return names;
	}
	
	/**
	 * get string
	 * @param name
	 * @return String
	 */
	public String getString(String name) {
		Object value = get(name);
		return value == null ? null : value.toString();
	}
	
	/**
	 * get string
	 * @param name
	 * @return String
	 */
	public String getString(String name, String defaultValue) {
		return get(name, defaultValue).toString();
	}
	
	/**
	 * get int
	 * @param name
	 * @return int
	 */
	public int getInt(String name) {
		return getInt(name, 0);
	}
	
	/**
	 * get int
	 * @param name
	 * @param defaultValue
	 * @return int
	 */
	public int getInt(String name, int defaultValue) {
		String value = getString(name, "");
		return "".equals(value) ? defaultValue : Integer.parseInt(value);
	}
	
	/**
	 * get double
	 * @param name
	 * @return double
	 */
	public double getDouble(String name) {
		return getDouble(name, 0);
	}
	
	/**
	 * get double
	 * @param name
	 * @param defaultValue
	 * @return double
	 */
	public double getDouble(String name, double defaultValue) {
		String value = getString(name, "");
		return "".equals(value) ? defaultValue : Double.parseDouble(value);
	}
	
	/**
	 * get boolean
	 * @param name
	 * @return boolean
	 */
	public boolean getBoolean(String name) {
		return getBoolean(name, false);
	}
	
	/**
	 * get boolean
	 * @param name
	 * @param defaultValue
	 * @return boolean
	 */
	public boolean getBoolean(String name, boolean defaultValue) {
		String value = getString(name, "");
		return "".equals(value) ? defaultValue : Boolean.valueOf(value).booleanValue();
	}
	
	/**
	 * get data
	 * @param name
	 * @return IData
	 */
	public IData getData(String name) {
		return (IData) get(name);
	}
	
	/**
	 * get data
	 * @param name
	 * @return IDataset
	 */
	public IDataset getDataset(String name) {
		return (IDataset) get(name);
	}
	
	/**
	 * to dataset
	 * @return IDataset
	 */
	public IDataset toDataset() throws Exception {
		int size = 0;
		IDataset dataset = new DatasetList();
		String[] names = getNames();
		for (int i=0; i<names.length; i++) {
			if (get(names[i]) instanceof List) {
				List list = (List) get(names[i]);
				if (size < list.size()) {
					size = list.size();
				}
			}
		}
		for (int i=0; i<size; i++) {
			IData data = new DataMap();
			for (int j=0; j<names.length; j++) {				
				Object obj = get(names[j]);
				if (obj instanceof List) {
					List list = (List) obj;
					if (i < list.size()) {
						data.put(names[j], list.get(i));
					} else {
						data.put(names[j], "");
					}
				} else {
					data.put(names[j], obj);
				}
			}
			dataset.add(data);
		}
		return dataset;
	}
	
	/**
	 * to string
	 * @return String
	 */
    public String toString() {
    	StringBuffer str = new StringBuffer();
    	str.append("{");
    	
    	Iterator it = entrySet().iterator();
    	while (it.hasNext()) {
    		Entry entity = (Entry) (it.next());
    		Object key = entity.getKey();
    		Object value = entity.getValue();
    		str.append("\"" + key + "\":");
    		
    		if (value == null) {
    			str.append("\"\"");
      		} else if (value instanceof Map || value instanceof List) {
        		str.append(value);
    		} else {
    			str.append("\"" + value + "\"");
    		}
    		
    		if (it.hasNext()) str.append(",");
    	}
    	
    	str.append("}");
    	return str.toString();
	}
    
	/**
	 * to wade string
	 * @return String
	 */
    public String toWadeString() {
    	StringBuffer str = new StringBuffer();
    	str.append("{");
    	
    	Iterator it = entrySet().iterator();
    	while (it.hasNext()) {
    		Entry entity = (Entry) (it.next());
    		Object key = entity.getKey();
    		Object value = entity.getValue();
    		str.append(key + "=");
    		
    		if (value == null) {
    			str.append("[\"\"]");
    		} else if (value instanceof JSONObject) {
    			IData object = new DataMap();
    			object.putAll((Map) value);
    			str.append(object.toWadeString());
      		} else if (value instanceof JSONArray) {
    			IDataset object = new DatasetList();
    			object.addAll((List) value);
    			str.append(object.toWadeString());
    		} else if (value instanceof Map) {
        		str.append(((IData) value).toWadeString());
    		} else if (value instanceof List) {
        		str.append(((IDataset) value).toWadeString());
    		} else {
    			str.append("[\"" + value + "\"]");
    		}
    		
    		if (it.hasNext()) str.append(", ");
    	}
    	
    	str.append("}");
    	return str.toString();
	}
    
	/**
	 * to bude string
	 * @return String
	 */
    public String toBudeString() {
    	StringBuffer str = new StringBuffer();
    	str.append("{");
    	
    	Iterator it = entrySet().iterator();
    	while (it.hasNext()) {
    		Entry entity = (Entry) (it.next());
    		Object key = entity.getKey();
    		Object value = entity.getValue();
    		str.append(key + "=");
    		
    		if (value == null) {
    			str.append("[\"\"]");
    		} else if (value instanceof JSONObject) {
    			IData object = new DataMap();
    			object.putAll((Map) value);
    			str.append(object.toBudeString());
      		} else if (value instanceof JSONArray) {
    			IDataset object = new DatasetList();
    			object.addAll((List) value);
    			str.append(object.toBudeString());
    		} else if (value instanceof Map) {
        		str.append(((IData) value).toBudeString());
    		} else if (value instanceof List) {
        		str.append(((IDataset) value).toBudeString());
    		} else {
    			str.append("[\"" + value.toString().replaceAll("\\\\", "\\\\\\\\").replaceAll("\\\"", "\\\\\"") + "\"]");
    		}
    		
    		if (it.hasNext()) str.append(", ");
    	}
    	
    	str.append("}");
    	return str.toString();
	}
	
}